package com.avit.tv.kui.toast;

import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.WindowManager;
import com.avit.tv.kui.AvitPartChildMarqueeView;
import com.avit.tv.kui.background.BgDrawable;
import com.avit.tv.kui.utils.Log;
import com.avit.tv.kui.utils.Utils;

import java.lang.ref.WeakReference;

/**
 * toast 弹窗
 *
 * @author like
 * @date 2020/8/4
 */
public class AvitToast {

    private volatile static AvitToast instance;
    private AvitPartChildMarqueeView rootView;
    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;
    private long toastShowTime;
    private final ShowHandler showHandler;
    private final BgDrawable drawable;

    private AvitToast() {
        showHandler = new ShowHandler(new WeakReference<>(this));
        drawable = new BgDrawable();
    }

    public static AvitToast makeToast() {
        if (instance == null)
            synchronized (AvitToast.class) {
                if (instance == null)
                    instance = new AvitToast();
            }
        return instance;
    }

    public void init(Context context) {
        initDefaultRoot(context);
        initWindowManager(context);
        toastShowTime = Configuration.LENGTH_SHORT;
    }

    private void initDefaultRoot(Context context) {
        int radix = Utils.getRadix(context);
        rootView = new AvitPartChildMarqueeView(context.getApplicationContext());
        rootView.setFocused(true);
        rootView.setGravity(Gravity.CENTER);
        drawable.setBgColor(Color.DKGRAY).setRadius(radix * 15).targetDrawable(rootView);

    }

    /**
     * 初始化 manager
     *
     * @param context
     */
    private void initWindowManager(Context context) {
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        layoutParams = new WindowManager.LayoutParams();
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        layoutParams.format = PixelFormat.TRANSPARENT;
        setGravity(Gravity.BOTTOM);
    }

    /**
     * 填充value
     *
     * @param massage
     * @return
     */

    public AvitToast makeText(String massage) {
        return makeText(massage, toastShowTime);
    }

    public AvitToast makeText(String massage, long showTime) {
        float measureText = rootView.getPaint().measureText(massage);
        int textWidth = Math.round(measureText + 100);
        calculateRect(textWidth);
        this.toastShowTime = showTime;
        rootView.setText(massage);
        return this;
    }


    /**
     * 计算 rootView 大小
     *
     * @param textWidth
     */
    private void calculateRect(int textWidth) {
        Context context = rootView.getContext();
        float textSize = rootView.getTextSize();
        int widthPixels = context.getResources().getDisplayMetrics().widthPixels - layoutParams.height;
        rootView.setMinHeight(Math.round(3 * textSize));
        rootView.setMinWidth(Math.min(widthPixels, textWidth));
    }


    /**
     * 设置toast 所在的位置
     *
     * @param gravity
     * @return
     */
    public AvitToast setGravity(int gravity) {
        layoutParams.gravity = gravity;
        layoutParams.verticalMargin = 0f;
        layoutParams.horizontalMargin = 0f;
        switch (gravity) {
            case Gravity.BOTTOM:
            case Gravity.TOP:
                layoutParams.verticalMargin = 0.01f;
                break;
            case Gravity.LEFT:
            case Gravity.RIGHT:
                layoutParams.horizontalMargin = 0.01f;
                break;
        }
        return this;
    }


    /**
     * show toast
     */
    public void show() {
        showHandler.toastShow();
    }


    /**
     * show toast
     */
    private void showToast() {
        if (rootView == null) {
            Log.w(this, "toast main viewer has been not inited");
            return;
        }

        try {
            if (rootView.getParent() != null) {
                Log.w(this, "window parent is not null , this may only change view shown value");
                windowManager.updateViewLayout(rootView, layoutParams);
            } else
                windowManager.addView(rootView, layoutParams);
        } catch (Exception e) {
            Log.w(this, "it may add toast error");
            e.printStackTrace();
        }
    }


    private void dismissToast() {
        if (rootView.getParent() != null) {
            try {
                windowManager.removeViewImmediate(rootView);
            } catch (Exception e) {
                Log.w(this, "it may not removeView success");
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取toast 的根View 进一步进行自定义处理【比如添加图标，等等】
     *
     * @return
     */
    public AvitPartChildMarqueeView getRootView() {
        return rootView;
    }

    /**
     * 重置toast 布局
     */
    public void reSetDefaultToast() {
        if (drawable != null && rootView != null) {
            drawable.targetDrawable(rootView);
        }
    }

    private static final class ShowHandler extends Handler {
        private final WeakReference<AvitToast> reference;
        private final static int TOAST_SHOW = 0x0001;
        private final static int TOAST_DISMISS = 0xffff;

        public ShowHandler(WeakReference<AvitToast> reference) {
            this.reference = reference;
        }

        public void toastShow() {
            removeMessages(TOAST_SHOW);
            sendEmptyMessage(TOAST_SHOW);
        }

        public void toastDismiss(long lazyTime) {
            removeMessages(TOAST_SHOW);
            removeMessages(TOAST_DISMISS);
            sendEmptyMessageDelayed(TOAST_DISMISS, lazyTime);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (isWeakRight()) {
                AvitToast avitToast = reference.get();
                switch (msg.what) {
                    case TOAST_SHOW:
                        avitToast.showToast();
                        toastDismiss(avitToast.toastShowTime);
                        break;
                    case TOAST_DISMISS:
                        avitToast.dismissToast();
                        break;
                }
            }

        }

        private boolean isWeakRight() {
            return reference != null && reference.get() != null;
        }
    }


    public final static class Configuration {

        // 控制toast显示的时间长短
        static final long LENGTH_LONG = 5000L;
        static final long LENGTH_SHORT = 2000L;

    }

}
